/*
#include <stdlib.h>

#define FALSE 0
#define TRUE 1

static Image * _pad_image(Image * Gray);

static Image * _pad_image(Image * Gray) {

	unsigned char * gray;

	Image * Pad;
	unsigned char * pad;

	int columns;
	int rows;
	int r, c;
	long int _r, i;

	int columnsg;
	int rowsg;
	long int _rg, ig;

	columnsg = Gray->width;
	rowsg = Gray->height;
	gray = Gray->data;

	Pad = image_new(columnsg + 2, rowsg + 2, IMAGE_PALETTE_GRAY);

	columns = Pad->width;
	rows = Pad->height;
	pad = Pad->data;

	_rg = 0;
	for (r = 0, _r = r * columns; r < rows; r++, _r += columns) {

		_rg += columnsg;

		for (c = 0; c < columns; c++) {
			i = _r + c;
			ig = _rg + (c - 1);

			if (r == 0 || c == 0 || r == rows - 1 || c == columns - 1)
				pad[i] = 255;
			else
				pad[i] = gray[ig];
		}
	}

	return Pad;
}

Image * imp_moore_neighbor_tracing(Image * Gray, Image ** Contour) {


	int inside = FALSE;
	int pos = 0;

	int rows, columns;
	
	long int i;

	rows = Gray->height;
	columns = Gray->width;

	// Need to start by padding the Gray by 1 Image
	Image * Pad = _pad_image(Gray);

	// Allocate new Gray as a 1D array
	Image * Border = image_new(columns + 2, rows + 2, IMAGE_PALETTE_GRAY);
	
	// Set entire Gray to WHITE
	for (i = 0; i < Border->size; i++) {
		Border->data[i] = 255;
	}

	for (int y = 0; y < (rows + 2); y++) {
		for (int x = 0; x < (columns + 2); x++) {
			pos = x + y * (columns + 2);

			// Scan for BLACK Image
			if (borderImage[pos] == BLACK && !inside) // Entering an already discovered border
			{
				inside = true;
			} else if (paddedImage[pos] == BLACK && inside) // Already discovered border point
			{
				continue;
			} else if (paddedImage[pos] == WHITE && inside) // Leaving a border
			{
				inside = false;
			} else if (paddedImage[pos] == BLACK && !inside) // Undiscovered border point
			{
				borderImage[pos] = BLACK; // Mark the start Image
				int checkLocationNr = 1; // The neighbor number of the location we want to check for a new border point
				int checkPosition; // The corresponding absolute array address of checkLocationNr
				int newCheckLocationNr; // Variable that holds the neighborhood position we want to check if we find a new border at checkLocationNr
				int startPos = pos; // Set start position
				int counter = 0; // Counter is used for the jacobi stop criterion
				int counter2 = 0; // Counter2 is used to determine if the point we have discovered is one single point

				// Defines the neighborhood offset position from current position and the neighborhood
				// position we want to check next if we find a new border at checkLocationNr
				int neighborhood[8][2] = {
					{-1, 7},
					{-3 - columns, 7},
					{-columns - 2, 1},
					{-1 - columns, 1},
					{1, 3},
					{3 + columns, 3},
					{columns + 2, 5},
					{1 + columns, 5}
				};
				// Trace around the neighborhood
				while (true) {
					checkPosition = pos + neighborhood[checkLocationNr - 1][0];
					newCheckLocationNr = neighborhood[checkLocationNr - 1][1];

					if (paddedImage[checkPosition] == BLACK) // Next border point found
					{
						if (checkPosition == startPos) {
							counter++;

							// Stopping criterion (jacob)
							if (newCheckLocationNr == 1 || counter >= 3) {
								// Close loop
								inside = true; // Since we are starting the search at were we first started we must set inside to true
								break;
							}
						}

						checkLocationNr = newCheckLocationNr; // Update which neighborhood position we should check next
						pos = checkPosition;
						counter2 = 0; // Reset the counter that keeps track of how many neighbors we have visited
						borderImage[checkPosition] = BLACK; // Set the border Image
					} else {
						// Rotate clockwise in the neighborhood
						checkLocationNr = 1 + (checkLocationNr % 8);
						if (counter2 > 8) {
							// If counter2 is above 8 we have traced around the neighborhood and
							// therefor the border is a single black Image and we can exit
							counter2 = 0;
							break;
						} else {
							counter2++;
						}
					}
				}
			}
		}
	}

	// Remove white padding and return it
	Image * clippedBorderImage = (Image *) malloc(sizeof (Image) * (rows) * (columns));
	for (int x = 0; x < columns; x++) {
		for (int y = 0; y < rows; y++) {
			clippedBorderImage[x + y * columns] = borderImage[x + 1 + (y + 1)*(columns + 2)];
		}
	}
	return clippedBorderImage;
}

pixel * mooreNeighborTracing(pixel * image, int width, int height) {
	bool inside = false;
	int pos = 0;

	// Need to start by padding the image by 1 pixel
	pixel * paddedImage = padImage(image, width, height, WHITE);

	// Allocate new image as a 1D array
	pixel * borderImage = (pixel *) malloc(sizeof (pixel) * (height + 2) * (width + 2));

	// Set entire image to WHITE
	for (int y = 0; y < (height + 2); y++) {
		for (int x = 0; x < (width + 2); x++) {
			borderImage[x + y * (width + 2)] = WHITE;
		}
	}

	for (int y = 0; y < (height + 2); y++) {
		for (int x = 0; x < (width + 2); x++) {
			pos = x + y * (width + 2);

			// Scan for BLACK pixel
			if (borderImage[pos] == BLACK && !inside) // Entering an already discovered border
			{
				inside = true;
			} else if (paddedImage[pos] == BLACK && inside) // Already discovered border point
			{
				continue;
			} else if (paddedImage[pos] == WHITE && inside) // Leaving a border
			{
				inside = false;
			} else if (paddedImage[pos] == BLACK && !inside) // Undiscovered border point
			{
				borderImage[pos] = BLACK; // Mark the start pixel
				int checkLocationNr = 1; // The neighbor number of the location we want to check for a new border point
				int checkPosition; // The corresponding absolute array address of checkLocationNr
				int newCheckLocationNr; // Variable that holds the neighborhood position we want to check if we find a new border at checkLocationNr
				int startPos = pos; // Set start position
				int counter = 0; // Counter is used for the jacobi stop criterion
				int counter2 = 0; // Counter2 is used to determine if the point we have discovered is one single point

				// Defines the neighborhood offset position from current position and the neighborhood
				// position we want to check next if we find a new border at checkLocationNr
				int neighborhood[8][2] = {
					{-1, 7},
					{-3 - width, 7},
					{-width - 2, 1},
					{-1 - width, 1},
					{1, 3},
					{3 + width, 3},
					{width + 2, 5},
					{1 + width, 5}
				};
				// Trace around the neighborhood
				while (true) {
					checkPosition = pos + neighborhood[checkLocationNr - 1][0];
					newCheckLocationNr = neighborhood[checkLocationNr - 1][1];

					if (paddedImage[checkPosition] == BLACK) // Next border point found
					{
						if (checkPosition == startPos) {
							counter++;

							// Stopping criterion (jacob)
							if (newCheckLocationNr == 1 || counter >= 3) {
								// Close loop
								inside = true; // Since we are starting the search at were we first started we must set inside to true
								break;
							}
						}

						checkLocationNr = newCheckLocationNr; // Update which neighborhood position we should check next
						pos = checkPosition;
						counter2 = 0; // Reset the counter that keeps track of how many neighbors we have visited
						borderImage[checkPosition] = BLACK; // Set the border pixel
					} else {
						// Rotate clockwise in the neighborhood
						checkLocationNr = 1 + (checkLocationNr % 8);
						if (counter2 > 8) {
							// If counter2 is above 8 we have traced around the neighborhood and
							// therefor the border is a single black pixel and we can exit
							counter2 = 0;
							break;
						} else {
							counter2++;
						}
					}
				}
			}
		}
	}

	// Remove white padding and return it
	pixel * clippedBorderImage = (pixel *) malloc(sizeof (pixel) * (height) * (width));
	for (int x = 0; x < width; x++) {
		for (int y = 0; y < height; y++) {
			clippedBorderImage[x + y * width] = borderImage[x + 1 + (y + 1)*(width + 2)];
		}
	}
	return clippedBorderImage;
}
*/

